package momo.app.multicast.presence;

import java.util.Map;
import java.util.Set;

import momo.app.multicast.Msg;
import momo.app.multicast.MsgRcvListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;



/**
 * This class form a layer between PresenceCallback and NodeCallback.
 * @author asa
 *
 */
public class MsgRcvListenerImpl implements MsgRcvListener {
	
	private Log log = LogFactory.getLog(MsgRcvListener.class);
    private MsgRcvListener msg_rcv_listener;
    private PresenceMulticastComm presence_multicast_comm;
    
    public MsgRcvListenerImpl(PresenceMulticastComm presence_multicast_comm) {
        this.msg_rcv_listener = null;
        this.presence_multicast_comm = presence_multicast_comm;
    }

	@Override
	public void msgLost(Map<String, Set<Integer>> lostMsg) {
		msg_rcv_listener.msgLost(lostMsg);
		
	}

    /**
     * Forward messages with type Message.TYPE_NORMAL to PresenceCallback.
     * Pass messages with type Message.TYPE_PRESENCE to Presence.
     */
	@Override
	public void msgReceived(Msg msg) {
        Message message_copy = Message.unmarshall(msg.getContents());
        switch (message_copy.getMessageType()) {
            case Message.TYPE_NORMAL:
            	if (presence_multicast_comm.getNetworkState().equals(NetworkState.CONNECTED) 
            			&& msg_rcv_listener != null) {
                	msg.setContents((String)message_copy.getContent());
            		msg_rcv_listener.msgReceived(msg);
            	}
                break;
            case Message.TYPE_PRESENCE:
            	if (presence_multicast_comm.getPresence() != null 
            			&& (presence_multicast_comm.getNetworkState().equals(NetworkState.ACKNOWLEDGED) ||
            					presence_multicast_comm.getNetworkState().equals(NetworkState.CONNECTED)))
            		presence_multicast_comm.getPresence().onReceivePresenceMessage(
            				(PresenceMessage)message_copy.getContent());
                break;
            case Message.TYPE_NEW_PEER_JOIN:
            	log.debug("new peer joined");
            	if (presence_multicast_comm.getNetworkState().equals(NetworkState.CONNECTED) &&
            			presence_multicast_comm.getPresence() != null) {
            		presence_multicast_comm.getPresence().handleNewPeerJoin();
//            		presence_multicast_comm.getPresence().resetRTTTimeout();
//            		presence_multicast_comm.getPresence().cancelPresence();
            	}
                break;
            case Message.TYPE_ACKNOWLEDGEMENT:
            	presence_multicast_comm.onReceiveAcknowledgement();
            	break;
        }
	}

	public void setMsgRcvListener(MsgRcvListener msg_rcv_listener) {
		this.msg_rcv_listener = msg_rcv_listener;
	}
}
